//
//  BlipMessage.m
//  blipTest
//
//  Created by dawid on 08-12-14.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "BlipMessage.h"
#import "BlipRequestUpdate.h"
#import "BlipErrors.h"
#import "AppController.h"
#include <JSON/JSON.h>
#import "MessageView.h"
#import "RegexKitLite.h"
#import "NSAttributedString+AppKitExtensions.h"


@implementation BlipMessage
@synthesize attributedBody,youtubeQtLink, youtubeThumbnail;

-(id)initWithJSON:(NSDictionary*)jsonValues authorization:(NSString*)value;
{
	if (![super init]){
		return nil;
	}

	NSEnumerator *e = [jsonValues keyEnumerator];
	for (NSString *key in e){
		if (key == nil){
#ifdef __DEBUG__

			NSLog(@"key = nil");

#endif
			continue;
		}
		if ([key isEqualToString:@"id"] == YES){
			[self setMsgId:[jsonValues objectForKey:key]];
		} else if ([key isEqualToString:@"created_at"] == YES){
				[self setCreatedAt:[jsonValues objectForKey:key]];
		}
		else if ([key isEqualToString:@"body"] == YES){
			[self setBody:[jsonValues objectForKey:key]];
			//NSString* string = [jsonValues objectForKey:key];
			//[self setBody:[[NSString alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding] encoding:NSUTF8StringEncoding]];
		}
		else if ([key isEqualToString:@"type"] == YES){
			[self setMsgType:[jsonValues objectForKey:key]];
		}
		else if ([key isEqualToString:@"user_path"] == YES){
			[self setUserPath:[jsonValues objectForKey:key]];
		}
		else if ([key isEqualToString:@"pictures_path"] == YES){
			[self setPicturePath:[jsonValues objectForKey:key]];
		}
		else if ([key isEqualToString:@"recipient_path"] == YES){
			[self setRecipientPath:[jsonValues objectForKey:key]];
			
		}
		
		else{
#ifdef __DEBUG__

			//NSLog(@"do nothing for key:%@", key);

#endif
		}
	}
	userSex = @"m";
	authorizationString = value;


	return self;
	
}

-(NSString*)checkDownloadData:(NSData*)data
{
	NSString* dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];	
	[dataString autorelease];
	
	if ([BlipErrors findError:data] == YES){
		data = nil;
		return nil;
	}
	
	return 	dataString;
}
-(void)dealloc
{
	if (msgId){
	[msgId release];
		msgId=nil;
	}
	if (createdAt){
		[createdAt release];
		createdAt = nil;
	}
	if (body){
		[body release];
		body=nil;
	}
	if (msgType){
		[msgType release];
		msgType=nil;
	}
	if (userPath){
		[userPath release];
		userPath=nil;
		
	}
	if (picturePath){
		[picturePath release];
		picturePath=nil;
	}
	if(pictureData){
		[pictureData release];
		pictureData=nil;
	}
	if (recordingPath){
		[recordingPath release];
		recordingPath = nil;
	}
	if (moviePath){
		[moviePath release];
		moviePath = nil;
	}
	if (userAvatar){
		[userAvatar release];
		userAvatar = nil;
	}
	if (recipientAvatar){
		[recipientAvatar release];
		recipientAvatar=nil;
	}
	if (recipientPath){
		[recipientPath release];
		recipientPath=nil;
	}
	if (userName){
		[userName release];
		userName = nil;
	}
	if (recipientName){
		[recipientName release];
		recipientName=nil;
	}
	if (userAvatarPath){
		[userAvatarPath release];
		userAvatarPath=nil;
	}

	if (authorizationString){
		[authorizationString release];
		authorizationString = nil;
	}
	
	if (recipientAvatarPath){
		[recipientAvatarPath release];
		recipientAvatarPath  = nil;
	}
	if (userSex){
		[userSex release];
		userSex= nil;
	}
	if (attributedBody){
		[attributedBody release];
		attributedBody= nil;
	}
	if (youtubeQtLink){
		[youtubeQtLink release];
		youtubeQtLink = nil;
	}
	if (youtubeThumbnail){
		[youtubeThumbnail release];
		youtubeThumbnail = nil;
	}
	[super dealloc];
}
				
#pragma mark properties
-(void)setMsgId:(NSString*)messageId
{
	[messageId retain];
	[msgId release];
	msgId = messageId;
}
-(NSString*)msgId
{
	return msgId;
}
-(void)setCreatedAt:(NSString*)creationDate
{
	[creationDate retain];
	[createdAt release];
	
	createdAt = [NSCalendarDate dateWithString:creationDate calendarFormat:@"%Y-%m-%d %H:%M:%S"];
	
}
-(NSCalendarDate*)createdAt
{
	return createdAt;
}
-(void)setBody:(NSString*)msgText
{
	[msgText retain];
	[body release];
	body = msgText;
	attributedBody =  [[NSMutableAttributedString alloc] initWithString:body attributes:[MessageView blipTextAttributes]];
}
-(NSString*)body
{
	return body;
}
-(void)setMsgType:(NSString*)newType
{
	[newType retain];
	[msgType release];
	msgType = newType;
}
-(NSString*)msgType
{
	return msgType;
}
-(void)setUserPath:(NSString*)newUserPath
{
	[newUserPath retain];
	[userPath release];
	userPath = newUserPath;
	[self setUserName:[userPath lastPathComponent]];
}
-(NSString*)userPath
{
	return userPath;
}
-(void)setRecipientPath:(NSString*)newRecipientPath{
	[newRecipientPath retain];
	[recipientPath release];
	recipientPath = newRecipientPath;
	[self setRecipientName:[recipientPath lastPathComponent]];
}
-(NSString*)recipientPath
{
	return recipientPath;
}
-(void)setPicturePath:(NSString*)newPicturePath
{
	[newPicturePath retain];
	[picturePath release];
	picturePath = newPicturePath;
}
-(NSString*)picturePath
{
	return picturePath;
}
-(void)setPictureData:(NSData*)picture
{
	[picture retain];
	[pictureData release];
	pictureData = picture;
}

-(NSData*)pictureData
{
	return pictureData;
}
-(void)setUserAvatar:(NSData*)avatar
{
	[avatar retain];
	[userAvatar release];
	userAvatar = avatar;
}

-(NSData*)userAvatar
{
	return userAvatar;
}
-(void)setRecipientAvatar:(NSData*)avatar
{
	[avatar retain];
	[recipientAvatar release];
	recipientAvatar = avatar;
}
-(NSData*)recipientAvatar
{
	return recipientAvatar;
}
-(void)setUserName:(NSString*)newUserName
{
	[newUserName retain];
	[userName release];
	userName = newUserName;
}
-(NSString*)userName
{
	return userName;
	
}
-(void)setRecipientName:(NSString*)newRecipientName
{
	[newRecipientName retain];
	[recipientName release];
	recipientName = newRecipientName;
}
-(NSString*)recipientName
{
	return recipientName;
}
-(void)setUserAvatarPath:(NSString*)newPath
{
	[newPath retain];
	[userAvatarPath release];
	userAvatarPath =newPath;
}
-(NSString*)userAvatarPath
{
	return userAvatarPath;
}
-(void)setCanDeleteMessage:(BOOL)canDelete
{
	canDeleteMessage = canDelete;
}
-(BOOL)canDeleteMessage
{
	return canDeleteMessage;
}
-(void)setRecipientAvatarPath:(NSString*)newPath
{
	[newPath retain];
	[recipientAvatarPath release];
	recipientAvatarPath =newPath;
}
-(NSString*)recipientAvatarPath
{
	return recipientAvatarPath;
}
-(void)setUserSex:(NSString*)newOrientation
{
	[newOrientation retain];
	[userSex release];
	userSex =newOrientation;
}
-(NSString*)userSex
{
	return userSex;
}
#pragma mark download with includes


#pragma mark picture download functions
-(void)downloadAvatars
{
	if (userPath){

		[self downloadAvatar:userPath receiverType:NO];
	}
	
	if (recipientPath){
		[self downloadAvatar:recipientPath receiverType:YES];
	}
		
}
-(void)downloadAvatar:(NSString*)avatarPath receiverType:(BOOL)recipient
{
	
	NSString* temp ;
	if (recipient == NO){
		temp = userAvatarPath;// [NSString stringWithFormat:@"%@/avatar",[self userPath]];
	} else {
		temp = recipientAvatarPath;//[NSString stringWithFormat:@"%@/avatar",[self recipientPath]];
	}
	
/*	if ([[self msgType] isEqualToString:@"Notice"]){
		NSBundle *bundle = [NSBundle mainBundle];
		[self setUserAvatarPath:[bundle pathForResource:@"blip" ofType:@"png"]];
		return;
	}
*/
	if ([self checkAvatarExistance:temp userType:recipient]==YES){
		return;
	}
	BLP_URLRequestUpdate* avatarRequest = [[BLP_URLRequestUpdate alloc] initGetWithRelativePath:temp];
	NSData* urlData=[self sendRequest:avatarRequest];
	if (recipient == NO){
		temp = userAvatarPath;
	} else {
		temp = recipientAvatarPath;
	}
	avatarRequest = nil;
	if (!urlData){
#ifdef __DEBUG__

		NSLog(@"Cannot download avatar:%@",temp);

#endif
		return;
	}else {
		

		[self saveAvatar:temp avatarData:urlData isUser:!recipient];
	}
	
	urlData= nil;
	//[temp release];
	//[urlData release];
	//[urlRequest release];
	//urlRequest = nil;
	//[avatarPath release];
}
-(void)downloadSynchronousExtendedMsg
{

	BLP_URLRequestUpdate *request; 
	if (msgType == nil){
#ifdef __DEBUG__

		NSLog(@"msgtype =nil ");

#endif
	} else
	if ([msgType isEqualToString:ABL_STATUS_MESSAGE] ==YES ){
		request = [[BLP_URLRequestUpdate alloc] initWithUpdateDownload:msgId authorizationString:authorizationString];
	} else if ([msgType isEqualToString:ABL_DIRECTED_MESSAGE] ==YES ){
		request = [[BLP_URLRequestUpdate alloc] initWithDirectedDownload:msgId authorizationString:authorizationString];
	} else if ([msgType isEqualToString:ABL_PRIVATE_MESSAGE] ==YES ){
		request = [[BLP_URLRequestUpdate alloc] initWithPrivateDownload:msgId authorizationString:authorizationString];
	}
	else{
		NSBundle *bundle = [NSBundle mainBundle];
		[self setUserAvatarPath:[bundle pathForResource:@"blip" ofType:@"png"]];
		request = nil;
	}
	[self downloadQuote];
    NSData* urlData;
	if (request !=nil)
		urlData =[self sendRequest:request];
	else {
#ifdef __DEBUG__

		//NSLog(@"nie moge utworzyc request dla msgType:%@ , body = %@", [self msgType], [self body]);

#endif
		return;
	}

	if (!urlData){
#ifdef __DEBUG__

		NSLog(@"Cannot download extMessage");

#endif
		return;
	}
	NSString* respString = [self checkDownloadData:urlData];
	
	
	if (respString==nil){
		return;
	} else {
		NSMutableDictionary *jsonValues = [respString JSONValue];

		if (!jsonValues){
#ifdef __DEBUG__

			NSLog(@"jsonValues array is empty!!");

#endif
		}
		else{
			//wyciagniecie danych user'a
			NSMutableDictionary *dictToEdit = [jsonValues objectForKey:@"user"];
			NSString *stringToEdit;
			NSMutableDictionary *avatarValues;
			BLP_URLRequestUpdate *request;
#ifdef __DEBUG__

			//			NSLog(@"keys = %@", [dictToEdit allKeys]);

#endif
			if (dictToEdit!=nil){
				//plec - jest jeszcze login, background, id, location
				userSex = [dictToEdit objectForKey:@"sex"];
				
				//avatar
				avatarValues = [dictToEdit objectForKey:@"avatar"] ;
				stringToEdit = [avatarValues objectForKey:@"url_50"];
				if (stringToEdit ==nil){
					stringToEdit = [avatarValues objectForKey:@"url_90"];
					if (stringToEdit ==nil){
						stringToEdit = [avatarValues objectForKey:@"url_120"];
						if (stringToEdit ==nil){
							stringToEdit = [avatarValues objectForKey:@"url_30"];
						} else {
							userAvatarPath = stringToEdit;
						}
					}else {
						userAvatarPath = stringToEdit;
					}
				} else {
					userAvatarPath = stringToEdit;
				}
			//	userAvatarPath = 	 [[AppController appSupportDir] stringByAppendingPathComponent:userAvatarPath];

			}
			else
			{

			}
			dictToEdit = nil;
			dictToEdit = [jsonValues objectForKey:@"recipient"];
			if (dictToEdit!=nil){
				//avatar
				avatarValues = [dictToEdit objectForKey:@"avatar"] ;
				stringToEdit = [avatarValues objectForKey:@"url_50"];
				if (stringToEdit ==nil){
					stringToEdit = [avatarValues objectForKey:@"url_90"];
					if (stringToEdit ==nil){
						stringToEdit = [avatarValues objectForKey:@"url_120"];
						if (stringToEdit ==nil){
							stringToEdit = [avatarValues objectForKey:@"url_30"];
						} else {
							recipientAvatarPath = stringToEdit;
						}
					}else {
						recipientAvatarPath = stringToEdit;
					}
				} else {
					recipientAvatarPath = stringToEdit;
				}

			}
			else {

			}

			dictToEdit = nil;

			[self downloadAvatars];
				
			NSArray* arrayToEdit = [jsonValues objectForKey:@"pictures"];

			if ([arrayToEdit count]>0){
				dictToEdit = [arrayToEdit objectAtIndex:0];
				
				picturePath = [dictToEdit objectForKey:@"url"];
				[self downloadPicture];
				[request release];
				request = nil;
				
			}
		}
		//if ([body isMatchedByRegex:[BlipMessage regexDirectQuote] ]){
#ifdef __DEBUG__

		//	NSLog(@"mam dfa");

#endif
		//}
	
	}
	//ustawienie youtube
	NSString*youtubeLink = [[NSString stringWithString:body] stringByMatching:@"(http://)?(www\\.)?(youtube\\.com[^\\p{Z}]+)" options:RKLDotAll|RKLCaseless|RKLMultiline inRange:NSMakeRange(0, [body length]) capture:3 error:NULL];	
  if (!youtubeLink)
    return;

		NSError* err = nil;
		NSURL *urlYoutube =[NSURL URLWithString:[NSString stringWithFormat:@"http://%@",youtubeLink]];
	
		NSString *youtubeSite = [[NSString alloc] initWithContentsOfURL:urlYoutube
													  encoding:NSUTF8StringEncoding error:&err];
  
		if (err){
#ifdef __DEBUG__

			NSLog(@"Nie pobrano strony youtube");

#endif
			return;
		}
  NSString *vidId = [youtubeSite stringByMatching:@"&video_id=([^&]+)" capture:1];
  NSString *vidHash = [youtubeSite stringByMatching:@"&t=([^&]+)" capture:1];;
	
#ifdef __DEBUG__

	NSLog(@"%@ %@", vidId, vidHash);

#endif
    NSUInteger start = 0;
  NSString* timeString = [youtubeLink stringByMatching:@"#t=(.+)" capture:1];
  start = [[timeString stringByMatching:@"([\\p{N}]+)m" capture:1] intValue]*60;
  start += [[timeString stringByMatching:@"([\\p{N}]+)s" capture:1] intValue];
		// Note the use of &, referring to the address containing the pointer, not the value of the pointer.
		if (vidId && vidHash){
      NSString* fmt;
      if ([youtubeSite isMatchedByRegex:@"'IS_HD_AVAILABLE': true"]) {
        fmt = @"22";
      } else {
        fmt = @"18";
      }
      [self setYoutubeQtLink : [NSString stringWithFormat:@"http://www.youtube.com/get_video?fmt=%@&video_id=%@&t=%@&start=%d",fmt,vidId,vidHash, start]];
      NSString *path = [NSString stringWithFormat:@"http://img.youtube.com/vi/%@/default.jpg",vidId];
      path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
			//sciaganie thumbnail
			NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:path]];
			youtubeThumbnail = [self sendRequest:req];
		}

	}

-(void)downloadPicture
{
	if ([self picturePath]==nil){
		return;
	}
	BLP_URLRequestUpdate *pictRequest = [[BLP_URLRequestUpdate alloc] initGetWithUrl:[self picturePath] authotizationString:authorizationString] ;//initGetWithURL:[self picturePath]];
	NSData* urlData;
	int tryCount = 3;
	while (tryCount>0){
		tryCount--;
		urlData =[self sendRequest:pictRequest];
		
		if (!urlData){
#ifdef __DEBUG__

			NSLog(@"Cannot download picture:%@",picturePath);

#endif
			continue;
		}else {

			[self setPictureData:urlData];
			
		}
	}
	[pictRequest release];
	pictRequest  = nil;
	
}
-(void)downloadQuote
{
  NSString* matchString = [[self attributedBody] mutableString];
  
  NSArray* matchedQuotes = [matchString arrayOfCaptureComponentsMatchedByRegex:@"http://(www.)?blip.pl/([a-zA-Z]{1,3})/([0-9]+)" options:RKLCaseless|RKLDotAll|RKLMultiline range:NSMakeRange(0, [matchString length]) error:NULL];
  for (NSArray* matches in matchedQuotes) {
    NSString *matchedString = [matches objectAtIndex:3];
    NSString *type = [matches objectAtIndex:2];
    NSRange matchRange = [[[self attributedBody] mutableString] rangeOfString:[matches objectAtIndex:0]];
    BLP_URLRequestUpdate *quoteRequest;
    NSData* downloadData;
    NSMutableDictionary *jsonValues;
    NSMutableDictionary* quoteAttribute;
    BlipMessage* quoteMessage;
    if (matchedString!=nil && type!=nil){
      if ([type isEqualToString:@"s"]){
        quoteRequest = [[BLP_URLRequestUpdate alloc] initWithUpdateDownload:matchedString authorizationString:[[AppController shared]userPassword]];
      } else if ([type isEqualToString:@"dm"]){
  				quoteRequest = [[BLP_URLRequestUpdate alloc] initWithDirectedDownload:matchedString authorizationString:[[AppController shared]userPassword]];
      } else if ([type isEqualToString:@"pm"]){
        quoteRequest = [[BLP_URLRequestUpdate alloc] initWithPrivateDownload:matchedString authorizationString:[[AppController shared]userPassword]];
      } else{
        continue;
      }
      
      downloadData  = [self sendRequest:quoteRequest];
			if (downloadData && [BlipErrors findError:downloadData] == NO){
				jsonValues = [[[NSString alloc] initWithData:downloadData encoding:NSUTF8StringEncoding] JSONValue];
				if (jsonValues){
          quoteMessage = [[BlipMessage alloc] initWithJSON:jsonValues authorization:[[AppController shared]userPassword]];
					quoteAttribute = [NSMutableDictionary dictionaryWithObject:[NSString stringWithFormat:@"^%@:\n%@",[[jsonValues objectForKey:@"user"] objectForKey:@"login"],[quoteMessage body]]
                                                              forKey: NSToolTipAttributeName];
					[attributedBody addAttributes:quoteAttribute  range:matchRange];
				}
				
				
				if (quoteMessage){
					[quoteMessage release];
					quoteMessage = nil;
				}
				if (jsonValues){
					[jsonValues  release];
					jsonValues = nil;
				}
				
				
			}
    };
  }
}

#pragma mark url functions
-(NSData*)sendRequest:(NSURLRequest*)request
{
	NSData *urlData;
	NSURLResponse *responce;
	NSError *error;
	NSURL *urlResp ;
	int tryCount = CONN_TRY_COUNT;
	
	while (tryCount >0){
		tryCount--;
		urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responce error:&error];
		urlResp = [[NSURL alloc]init];
		urlResp= [responce URL];
		if (!urlData){
#ifdef __DEBUG__

			NSLog(@"urlData=nil in sendRequest");

#endif
			continue;
		}
		
		if ([BlipErrors findError:urlData] == YES){
			urlData = nil;
			continue;
			
		}
		break;
	}

	[urlResp release];
	urlResp =nil;
	
	return 	urlData;
}

#pragma mart FileFunctions
-(BOOL)checkAvatarExistance:(NSString*)avatarPath userType:(BOOL)recipient
{
	NSFileManager *fm = [NSFileManager defaultManager];
	NSString *avPath = [NSString stringWithFormat:@"%@", avatarPath];
	avPath = 	 [[AppController appSupportDir] stringByAppendingPathComponent:avPath];
	if (recipient==NO){
		[self setUserAvatarPath:avPath];
	} else {
		[self setRecipientAvatarPath:avPath];
	}

	if ([fm fileExistsAtPath:avPath] == YES){
		
		return YES;
	}
	return NO;
	
}
-(void)saveAvatar:(NSString*)avatarPath avatarData:(NSData*)data isUser:(BOOL)notRecipient
{
	NSFileManager *fm = [NSFileManager defaultManager];
	
	//avatarPath = [[AppController appSupportDir] stringByAppendingPathComponent:avatarPath];

	NSError *error;
	if ([fm fileExistsAtPath:avatarPath] == NO){
		if ([fm createDirectoryAtPath:[avatarPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&error]==NO){
#ifdef __DEBUG__

			NSLog(@"Error while creating directory:%@", [error description]);

#endif	
			return;
			
		} 
		if (![fm createFileAtPath:avatarPath contents:data attributes:nil]){
#ifdef __DEBUG__

			NSLog(@"Cannot create file:%@", avatarPath);

#endif
		}
	}
	
	return;
	
}
//+(id)regexQuote
//{
//	static RKRegex *regex = nil;
//	if (!regex){
//		regex = [RKRegex regexWithRegexString:@"http://(www.)?blip.pl/([a-zA-Z]{1,3})/([0-9]+)" options:RKCompileCaseless];
//	}
//	return regex;
//}
//+(id)regexDirectQuote
//{
//	static RKRegex *regex = nil;
//	if (!regex){
//		//regex = [RKRegex regexWithRegexString:@"^\\^.*?cytuje.*?http://(www.)?blip.pl/([a-zA-Z]{1,3})/([0-9]+).*?$" options:RKCompileCaseless];
//		regex = [RKRegex regexWithRegexString:@"^.*Cie cytuje.*" options:RKCompileCaseless];
//	}
//	return regex;
//}
@end
